package ongd.web;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import ongd.negocio.gestion.Apadrinado;
import ongd.negocio.gestion.ControladorApadrinamiento;
import ongd.negocio.gestion.ControladorPadrino;
import ongd.negocio.gestion.ControladorSocio;
import ongd.negocio.gestion.Persona;
import ongd.negocio.gestion.Proyecto;
import ongd.servicios.persistencia.exceptions.IllegalOrphanException;
import ongd.servicios.persistencia.exceptions.NonexistentEntityException;
import ongd.servicios.persistencia.exceptions.PreexistingEntityException;
import org.primefaces.context.RequestContext;

/**
 * Clase que se encargará de listar los socios o padrinos dados de baja.
 *
 * @author <a href="mailto:egi0002@alu.ubu.es">Elena García Iglesias</a>
 * @author <a href="mailto:cms0021@alu.ubu.es">Cristina Martínez Sanz</a>
 * @version 1.0 20120124
 *
 */
@ManagedBean
@ViewScoped
public class Listado_BajaPersona extends ABean {

    /**
     * Objeto de tipo ControladorSocio que nos servirá para realizar las 
     * operaciones relacionadas con los socios.
     */
    private ControladorSocio contSocio;
    /**
     * Objeto de tipo ControladorPadrino que nos servirá para realizar las 
     * operaciones relacionadas con los padrinos.
     */
    private ControladorPadrino contPadrino;
    /**
     * Objeto de tipo ControladorApadrinamiento que nos servirá para 
     * realizar las operaciones necesarias para los apadrinamientos.
     */
    private ControladorApadrinamiento contApadrinamiento;
    /**
     * Objeto de tipo personas que va a contener una persona seleccionada.
     */
    private Persona persona;
    /**
     * Objeto de tipo List que contiene todas las personas dadas de baja 
     * de la base de datos.
     */
    private List<Persona> vctPersonas;
    /**
     * Objeto de tipo String que contiene el nombre del proyecto al que 
     * asociaremos el padrino dado de alta.
     */
    private String proyectoNombre;
    /**
     * Objeto de tipo Proyecto que contiene el proyecto al que 
     * asociaremos el padrino dado de alta
     */
    private Proyecto proyecto;
    /**
     * Objeto de tipo List que contendra una lista con los apadrinados 
     * disponibles de un determinado proyecto.
     */
    private List<Apadrinado> listaA;
    /**
     * Objeto de tipo apadrinado que corresponderá con el apadrinado
     * asociado a un padrino.
     */
    private Apadrinado apadrinado;
    /**
     * Objeto de tipo String que va a contener el título de la página donde
     * estemos.
     */
    private String titulo;

    /**Constructor de la clase.
     */
    public Listado_BajaPersona() {
        persona = new Persona();
        vctPersonas = new ArrayList<Persona>();
        proyecto = new Proyecto();
        listaA = new ArrayList<Apadrinado>();
        apadrinado = new Apadrinado();
    }

    /**
     * Método abstracto que se encargará de cargar los parámetros iniciales.
     */
    @Override
    public void cargaInicial() {
        if (!FacesContext.getCurrentInstance().isPostback()) {
            SesionBean sesion = getSesionBean();
            if (sesion.iniciadaSesion()) {
                if (sesion.getStrVariable().compareTo("socio") == 0) {
                    titulo = "Gestionar Bajas - Socios";
                    contSocio = sesion.getControladorSocio();
                    persona.setTipo("S");
                    vctPersonas = contSocio.obtenerListaPersonaBaja("S");

                } else if (sesion.getStrVariable().compareTo("padrino") == 0) {
                    titulo = "Gestionar Bajas - Padrinos";
                    contPadrino = sesion.getControladorPadrino();
                    contApadrinamiento = sesion.getControladorApadrinamiento();
                    persona.setTipo("P");
                    vctPersonas = contPadrino.obtenerListaPersonaBaja("P");
                }
            }
        }
    }

    /**
     * Método que dará de alta un socio y mostrará las opciones para dar
     * de alta un padrino.
     * @return null
     */
    public String darAlta() {
        if (getSesionBean().iniciadaSesion()) {
            RequestContext requestContext = RequestContext.getCurrentInstance();
            try {
                boolean resultado = false;
                if (contSocio != null) {
                    resultado = contSocio.darAltaPersona(persona);
                    vctPersonas = contSocio.obtenerListaPersonaBaja("S");
                    persona = new Persona();
                    if (resultado) {
                        requestContext.addCallbackParam("altaOK", true);
                    } else {
                        requestContext.addCallbackParam("noAlta", true);
                    }
                    resultado = false;
                } else if (contPadrino != null && contApadrinamiento != null) {
                    requestContext.addCallbackParam("altaPadrino", true);
                }
            } catch (IllegalOrphanException ex) {
                Logger.getLogger(Listado_BajaPersona.class.getName()).log(Level.SEVERE, null, ex);
            } catch (NonexistentEntityException ex) {
                Logger.getLogger(Listado_BajaPersona.class.getName()).log(Level.SEVERE, null, ex);
            } catch (Exception ex) {
                Logger.getLogger(Listado_BajaPersona.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return null;
    }

    /**
     * Método que devuelve una lista de String con el nombre de cada proyecto
     * de tipo apadrinamiento general o personal que existe en la base de datos.
     * @return availableP
     */
    public List<String> getAvailableP() {
        if (contApadrinamiento != null) {
            List<String> availableP = new ArrayList<String>();
            for (Proyecto p : contApadrinamiento.obtenerProyectosApadrinamientoDisponibles()) {
                String cadena = p.getNombre();
                availableP.add(cadena);
            }
            return availableP;
        }
        return null;
    }

    /**
     * Método que se encargará asignar un proyecto a un nuevo padrino.
     * @return null
     */
    public String asignarProyecto() {
        RequestContext requestContext = RequestContext.getCurrentInstance();
        if (contApadrinamiento != null) {
            proyecto = contApadrinamiento.buscarProyecto(proyectoNombre);
            proyectoNombre = new String();
            if (proyecto.esProyectoApadrinamientoGeneral()) {
                darAltaPadrino();
            } else if (proyecto.esProyectoApadrinamientoPersonal()) {
                listaA = contApadrinamiento.obtenerApadrinadosDisponibles(proyecto);
                requestContext.addCallbackParam("apadrinamientoPersonal", true);
            }
        }
        return null;
    }

    /**
     * Método que dará de alta un padrino.
     * @return null
     */
    public String darAltaPadrino() {
        if (getSesionBean().iniciadaSesion()) {
            if (contPadrino != null) {
                RequestContext requestContext = RequestContext.getCurrentInstance();
                try {
                    boolean resultado = false;
                    if (proyecto.esProyectoApadrinamientoPersonal()) {
                        if (apadrinado == null) {
                            requestContext.addCallbackParam("errorap", true);
                        } else {
                            //Doy de alta el padrino con el apadrinado
                            resultado = contPadrino.darAltaPersona(persona, proyecto, apadrinado);
                            apadrinado = new Apadrinado();
                        }
                    } else if (proyecto.esProyectoApadrinamientoGeneral()) {
                        resultado = contPadrino.darAltaPersona(persona, proyecto, null);
                    }
                    if (resultado) {
                        requestContext.addCallbackParam("altaOK", true);
                    } else {
                        requestContext.addCallbackParam("noAlta", true);
                    }
                    resultado = false;
                    vctPersonas = contPadrino.obtenerListaPersonaBaja("P");
                    persona = new Persona();
                    listaA = new ArrayList<Apadrinado>();
                    proyectoNombre = new String();
                    apadrinado = new Apadrinado();
                } catch (PreexistingEntityException ex) {
                    Logger.getLogger(Listado_BajaPersona.class.getName()).log(Level.SEVERE, null, ex);
                } catch (Exception ex) {
                    Logger.getLogger(Listado_BajaPersona.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        return null;
    }

    /**
     * Metodo que devuelve el valor de la variable contPadrino.
     * @return contPadrino
     * @see #setContPadrino
     */
    public ControladorPadrino getContPadrino() {
        return contPadrino;
    }

    /**
     * Método que establece el valor de la variable contPadrino.
     * @param contPadrino Nuevo valor de la variable
     * @see #getContPadrino
     */
    public void setContPadrino(ControladorPadrino contPadrino) {
        this.contPadrino = contPadrino;
    }

    /**
     * Método que devuelve el valor de la variable contSocio.
     * @return contSocio
     * @see #setContSocio
     */
    public ControladorSocio getContSocio() {
        return contSocio;
    }

    /**
     * Método que establece el valor de la variable contSocio.
     * @param contSocio Nuevo valor de la variable
     * @see #getContSocio
     */
    public void setContSocio(ControladorSocio contSocio) {
        this.contSocio = contSocio;
    }

    /**
     * Método que devuelve el valor de la variable persona.
     * @return persona
     * @see #setPersona
     */
    public Persona getPersona() {
        return persona;
    }

    /**
     * Método que establece el valor de la variable persona.
     * @param persona Nuevo valor de la variable
     * @see #getPersona
     */
    public void setPersona(Persona persona) {
        this.persona = persona;
    }

    /**
     * Método que de vuelve el valor de la variable vctPersonas.
     * @return vctPersonas
     * @see #setVctPersonas
     */
    public List<Persona> getVctPersonas() {
        return vctPersonas;
    }

    /**
     * Método que establece el valor de la variable vctPersonas.
     * @param vctPersonas Nuevo valor de la variable
     * @see #getVctPersonas
     */
    public void setVctPersonas(List<Persona> vctPersonas) {
        this.vctPersonas = vctPersonas;
    }

    /**
     * Método que devuelve el valor de la variable contApadrinamiento.
     * @return contApadrinamiento
     * @see #setContApadrinamiento
     */
    public ControladorApadrinamiento getContApadrinamiento() {
        return contApadrinamiento;
    }

    /**
     * Método que establece el valor de la variable contApadrinamiento.
     * @param contApadrinamiento Nuevo valor de la variable
     * @see #getContApadrinamiento
     */
    public void setContApadrinamiento(ControladorApadrinamiento contApadrinamiento) {
        this.contApadrinamiento = contApadrinamiento;
    }

    /**
     * Método que devuelve el valor de la variable proyectoNombre.
     * @return proyectoNombre
     * @see #setProyectoNombre
     */
    public String getProyectoNombre() {
        return proyectoNombre;
    }

    /**
     * Método que establece el valor de la variable proyectoNombre.
     * @param proyectoNombre Nuevo valor de la variable
     * @see #getProyectoNombre
     */
    public void setProyectoNombre(String proyectoNombre) {
        this.proyectoNombre = proyectoNombre;
    }

    /**
     * Método que devuelve el valor de la variable apadrinado.
     * @return apadrinado
     * @see #setApadrinado
     */
    public Apadrinado getApadrinado() {
        return apadrinado;
    }

    /**
     * Método que establece el valor de la variable apadrinado.
     * @param apadrinado Nuevo valor de la variable
     * @see #getApadrinado
     */
    public void setApadrinado(Apadrinado apadrinado) {
        this.apadrinado = apadrinado;
    }

    /**
     * Método que devuelve el valor de la listaA.
     * @return listaA
     * @see #setListaA
     */
    public List<Apadrinado> getListaA() {
        return listaA;
    }

    /**
     * Método que establece el valor de la listaA.
     * @param listaA Nuevo valor de la variable
     * @see #getListaA
     */
    public void setListaA(List<Apadrinado> listaA) {
        this.listaA = listaA;
    }

    /**
     * Método que devuelve el valor de la variable proyecto.
     * @return proyecto
     * @see #setProyecto
     */
    public Proyecto getProyecto() {
        return proyecto;
    }

    /**
     * Método que establece el valor de la variable proyecto.
     * @param proyecto Nuevo valor de la variable
     * @see #getProyecto
     */
    public void setProyecto(Proyecto proyecto) {
        this.proyecto = proyecto;
    }

    /**
     * Método que devuelve el valor de la variable titulo.
     * @return titulo
     * @see #setTitulo
     */
    public String getTitulo() {
        return titulo;
    }

    /**
     * Método que establece el valor de la variable título.
     * @param titulo Nuevo valor de la variable
     * @see #getTitulo
     */
    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }
}
